package zent

import (
	"bytes"
	"encoding/binary"
	"errors"
	"log"
	"studygo/sp/a/zinx/utils"
	"studygo/sp/a/zinx/ziface"
)

//封包
type DataPack struct {
	Name string
}

func NewDataPack() *DataPack {
	return &DataPack{}
}

//GetHeadLen 获取包的长度方法
func (d *DataPack) GetHeadLen() uint32 {
	//Id uint32[4个字节] |  DataLen uint32[4个字节]
	return 8
}

//Pack 封包
//|dataLen|msgID|data|
func (d *DataPack) Pack(msg ziface.Imessage) ([]byte, error) {
	log.Println(len(msg.GetData()), "|", msg.GetMsgLen())
	//创建一个 存放byte 字节的缓存
	dataBuff := bytes.NewBuffer([]byte{})

	//将 dataLen写进 dataBuff 中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgLen()); err != nil {
		return nil, err
	}
	//将 MsgId 写进 dataBuff 中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgId()); err != nil {
		return nil, err
	}
	//将 data 数据写进 dataBuff 中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetData()); err != nil {
		return nil, err
	}
	return dataBuff.Bytes(), nil
}

//Unpack 拆包
//将包的  head信息读取出来，之后根据head信息中的data长度读取一次
func (d *DataPack) Unpack(binaryData []byte) (ziface.Imessage, error) {
	//创建一个 从 输入 二进制 的数据ioReader
	var dataBuff = bytes.NewReader(binaryData)
	//只解压 head 信息，得到 datalen和 MsgID
	msg := &Message{}

	//此处要改变 值，因此是 地址
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.Id); err != nil {
		return nil, err
	}

	//判断是否已经超出了 允许最大包长度
	if utils.GlocalObject.MaxPackageSize > 0 && utils.GlocalObject.MaxPackageSize < msg.DataLen {
		return nil, errors.New("too large msg data recv!")
	}
	return msg, nil
}
